package Modelo;

import GUI.InicioAplicacion;
import Utils.Ficheros.FicheroDatos;
import Utils.CoordUTM;
import Utils.Util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * 
 * @author Doria
 */
public class CalculosDatos {

    private static int ancho;
    private static int alto;
    private static double longEsqIzq;
    private static double latEsqIzq;
    private static double longEsqDer;
    private static double latEsqDer;
    private static double escala;
    private static String datum;
    private static int numEllipsoid = 0;
    private static int numFilas;
    private static int numColumnas;
    private static String ficheroImagen;
    private static String extensionImagen;
    private static String rutaImagen;

    /*    public static boolean mapaValido(String mapa) {
    setInfoFichero(mapa);
    String ruta = InicioAplicacion.getControlador().getRuta();
    boolean valido = true;

    try {
    FileConnection ficheroRuta = (FileConnection) Connector.open(ruta);
    InputStream inputStreamRuta = ficheroRuta.openInputStream();
    FicheroDatos infoLinea = new FicheroDatos();
    infoLinea.lecturaFichero(inputStreamRuta);

    //Recorremos la ruta completamente y nos aseguramos que todos los
    //puntos caigan dentro de los mapas
    while ((infoLinea.getLatitud() != -1) && (infoLinea.getLongitud() != -1) &&
    (infoLinea.getAltitud() != 777) && valido) {
    if ((infoLinea.getLongitud() <= longEsqIzq) || (infoLinea.getLatitud() >= latEsqIzq) || (infoLinea.getLongitud() >= longEsqDer) ||
    (infoLinea.getLatitud() <= latEsqDer)) {
    valido = false;
    }
    infoLinea.lecturaFichero(inputStreamRuta);
    }
    try {
    inputStreamRuta.close();
    } catch (Exception ex) {
    InicioAplicacion.getControlador().muestraAlerta("Problema en " +
    "CalculosDatos al intentar cerrar el inputStream");
    ex.printStackTrace();
    }
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    return valido;
    }
     */
    /* Construye un mapa vacío por defecto */
    public static void setMapaVacio() {
        datum = "WGS 84";
        ancho = 1000;
        alto = 1000;
        longEsqIzq = 0;
        latEsqIzq = 0;
        longEsqDer = 0;
        latEsqDer = 0;
        escala = 1;
        numEllipsoid = 23;
    }

    /**
     * Método que carga los datos de un mapa descargado desde Google Maps
     * @param origen Coordenadas del punto central del mapa de google
     * @param ancho Anchura del mapa en píxeles
     * @param alto Altura del mapa en píxeles
     * @param dat Datum con el que se va a trabajar
     */
    public static void setInfoGoogle(FicheroDatos origen, int ancho, int alto, String dat) {
        escala = 0.917431;
        double[] latlon = Util.adjust(origen.getLatitud(),
                origen.getLongitud(),
                (int) (-1.5 * ancho), (int) (-1.5 * alto), InicioAplicacion.getControlador().getGeomantes().getNivelZoom());
        latEsqIzq = latlon[1];
        longEsqIzq = latlon[0];
        datum = dat;

    }

    public static void setInfoGoogle(FicheroDatos origen, int ancho, int alto, String dat, double escal) {
        escala = escal;
        double[] latlon = Util.adjust(origen.getLatitud(),
                origen.getLongitud(),
                (int) (-1.5 * ancho), (int) (-1.5 * alto), InicioAplicacion.getControlador().getGeomantes().getNivelZoom());
        latEsqIzq = latlon[1];
        longEsqIzq = latlon[0];
        datum = dat;
    }

    /**
     * Método que procesa el archivo .map y extrae los datos necesarios
     * para la geolocalización
     * @param mapa String que contiene los datos del fichero .map
     */
    public static void setInfoFichero(String mapa) {
        try {
            FileReader fc = new FileReader(mapa);
            BufferedReader inputStreamTxt = new BufferedReader(fc);
            int contador = 0;
            int c;
            c = inputStreamTxt.read();
            while (c != '\n') {
                c = inputStreamTxt.read();
            }
            StringBuffer sb = new StringBuffer();
            c = inputStreamTxt.read();
            char ch = (char) c;
            while (ch != '\n') {
                if (ch != '\r') {
                    sb.append(ch);
                }
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            ficheroImagen = sb.toString();
            sb.delete(0, sb.length());

            while (contador < 2) {
                c = inputStreamTxt.read();
                while ((c != '\n')) {
                    c = inputStreamTxt.read();
                }
                contador++;
            }

            c = inputStreamTxt.read();
            ch = (char) c;
            while (ch != ',') {
                sb.append(ch);
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            datum = sb.toString();

            while ((c != '\n')) {
                c = inputStreamTxt.read();
            }
            sb.delete(0, sb.length());
            String temp = "MMPXY";
            while (temp.compareTo(sb.toString()) != 0) {
                sb.delete(0, sb.length());
                while ((c != '\n')) {
                    c = inputStreamTxt.read();
                }
                int cont = 0;
                while (cont < 5) {
                    c = inputStreamTxt.read();
                    ch = (char) c;
                    sb.append(ch);
                    cont++;
                }
            }
            sb.delete(0, sb.length());
            while ((c != '\n')) {
                c = inputStreamTxt.read();
            }
            int cont = 0;
            while (cont < 7) {
                c = inputStreamTxt.read();
                cont++;
            }
            ch = (char) c;
            while (ch != ',') {
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            c = inputStreamTxt.read();
            ch = (char) c;
            while (ch != ',') {
                sb.append(ch);
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            ancho = Integer.parseInt(sb.toString());
            sb.delete(0, sb.length());
            while ((c != '\n')) {
                c = inputStreamTxt.read();
            }
            cont = 0;
            while (cont < 9) {
                c = inputStreamTxt.read();
                cont++;
            }
            ch = (char) c;
            while (ch != ',') {
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            c = inputStreamTxt.read();
            ch = (char) c;
            while (c <= '9' && c >= '0') {
                sb.append(ch);
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            String tmp = sb.toString();
            alto = Integer.parseInt(tmp);
            sb.delete(0, sb.length());
            temp = "MMPLL";
            while (temp.compareTo(sb.toString()) != 0) {
                sb.delete(0, sb.length());
                while ((c != '\n')) {
                    c = inputStreamTxt.read();
                }
                cont = 0;
                while (cont < 5) {
                    c = inputStreamTxt.read();
                    ch = (char) c;
                    sb.append(ch);
                    cont++;
                }
            }
            sb.delete(0, sb.length());
            cont = 0;
            while (cont < 4) {
                c = inputStreamTxt.read();
                cont++;
            }
            ch = (char) c;
            while (ch != ',') {
                sb.append(ch);
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            longEsqIzq = Double.parseDouble(sb.toString());
            sb.delete(0, sb.length());
            c = inputStreamTxt.read();
            ch = (char) c;
            while (c != '\n') {
                sb.append(ch);
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            latEsqIzq = Double.parseDouble(sb.toString());
            sb.delete(0, sb.length());
            c = inputStreamTxt.read();
            while (c != '\n') {
                c = inputStreamTxt.read();
            }
            cont = 0;
            while (cont < 9) {
                c = inputStreamTxt.read();
                cont++;
            }
            ch = (char) c;
            while (ch != ',') {
                sb.append(ch);
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            longEsqDer = Double.parseDouble(sb.toString());
            sb.delete(0, sb.length());
            c = inputStreamTxt.read();
            ch = (char) c;
            while (c != '\n') {
                sb.append(ch);
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            latEsqDer = Double.parseDouble(sb.toString());
            sb.delete(0, sb.length());
            temp = "MM1B";
            while (temp.compareTo(sb.toString()) != 0) {
                sb.delete(0, sb.length());
                while ((c != '\n')) {
                    c = inputStreamTxt.read();
                }
                cont = 0;
                while (cont < 4) {
                    c = inputStreamTxt.read();
                    ch = (char) c;
                    sb.append(ch);
                    cont++;
                }
            }
            sb.delete(0, sb.length());
            c = inputStreamTxt.read();
            c = inputStreamTxt.read();
            ch = (char) c;
            while (c != '\n') {
                sb.append(ch);
                c = inputStreamTxt.read();
                ch = (char) c;
            }
            escala = Double.parseDouble(sb.toString());
            fc.close();

            //Calculamos el número de mapas
            setNumFilas(0);
            setNumColumnas(0);

            //Obtenemos la ruta de la imagen
            int indice = 0;
            for (int i = 0; i < mapa.length(); i++) {
                if ((int) mapa.charAt(i) == 92) { //Código ASCII de '\' es 92
                    indice = i;
                }
            }
            rutaImagen = mapa.substring(0, indice + 1);
            if (ficheroImagen.endsWith("\\r")) {
                ficheroImagen.substring(0, ficheroImagen.length() - 2);
            }
            String stringtemp[] = GoogleMaps.split(ficheroImagen, '.');
            ficheroImagen = stringtemp[0];
            extensionImagen = "." + stringtemp[1];
            File fc1 = new File(rutaImagen + ficheroImagen + extensionImagen);

            //Si no existe una imagen única de mapa, recorremos en busca de índices
            if (!fc1.exists()) {
                int i, j;
                i = 0;
                j = 0;
                fc1 = new File(rutaImagen + ficheroImagen + "0_" + j + extensionImagen);
                while (fc1.exists()) {
                    j++;
                    fc1 = new File(rutaImagen + ficheroImagen + "0_" + j + extensionImagen);
                }
                fc1 = new File(rutaImagen + ficheroImagen + i + "_0" + extensionImagen);
                while (fc1.exists()) {
                    i++;
                    fc1 = new File(rutaImagen + ficheroImagen + i + "_0" + extensionImagen);
                }
                setNumFilas(i);
                setNumColumnas(j);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Método que calcula el desplazamiento en píxeles de la coordenada actual
     * con respecto al origen del mapa
     * @param infolinea Contiene los datos de la posición actual
     */
    public static int[] calcular(FicheroDatos infolinea) {
        double latitud = infolinea.getLatitud();
        double longitud = infolinea.getLongitud();
        datum = "WGS 84";
        //Si no hemos inicializado el numero de elipsoide, lo hacemos
        if (numEllipsoid == 0) {
            boolean encontrado = false;
            while (numEllipsoid < 25 && !encontrado) {
                if (Util.ellipsoid[numEllipsoid].getEllipsoidName().compareTo(datum) == 0) {
                    encontrado = true;
                } else {
                    numEllipsoid++;
                }
            }
        }
        if (numEllipsoid <= 24) {
            CoordUTM CoordUTMorigen = Util.LLtoUTM(numEllipsoid, latEsqIzq, longEsqIzq);
            CoordUTM CoordUTMdestino = Util.LLtoUTM(numEllipsoid, latitud, longitud);
            int posX = (int) (Math.abs(Math.floor((CoordUTMdestino.getUTMEasting() - CoordUTMorigen.getUTMEasting()) * (1 / escala))));
            int posY = (int) (Math.abs(Math.floor((CoordUTMdestino.getUTMNorthing() - CoordUTMorigen.getUTMNorthing()) * (1 / escala))));
            int centroX = 0;
            int centroY = 0;
            int[] resultado = {centroX, centroY, posX, posY};
            return resultado;
        } else {
            /*InicioAplicacion.getControlador().muestraAlerta("Problema en " +
            "CalculosDatos al hacer calculos.");*/
            return null;
        }

    }

    public static int[] calcular(double latitud, double longitud) {
        datum = "WGS 84";
        //Si no hemos inicializado el numero de elipsoide, lo hacemos
        if (numEllipsoid == 0) {
            boolean encontrado = false;
            while (numEllipsoid < 25 && !encontrado) {
                if (Util.ellipsoid[numEllipsoid].getEllipsoidName().compareTo(datum) == 0) {
                    encontrado = true;
                } else {
                    numEllipsoid++;
                }
            }
        }
        if (numEllipsoid <= 24) {
            CoordUTM CoordUTMorigen = Util.LLtoUTM(numEllipsoid, latEsqIzq, longEsqIzq);
            CoordUTM CoordUTMdestino = Util.LLtoUTM(numEllipsoid, latitud, longitud);
            int posX = (int) (Math.abs(Math.floor((CoordUTMdestino.getUTMEasting() - CoordUTMorigen.getUTMEasting()) * (1 / escala))));
            int posY = (int) (Math.abs(Math.floor((CoordUTMdestino.getUTMNorthing() - CoordUTMorigen.getUTMNorthing()) * (1 / escala))));
            int centroX = 0;
            int centroY = 0;
            int[] resultado = {centroX, centroY, posX, posY};
            return resultado;
        } else {
            /*InicioAplicacion.getControlador().muestraAlerta("Problema en " +
            "CalculosDatos al hacer calculos.");*/
            return null;
        }

    }

    public static int getAnchoMapa() {
        return ancho;
    }

    public static int getAltoMapa() {
        return alto;
    }

    public static double getLongEsqIzq() {
        return longEsqIzq;
    }

    public static double getLatEsqIzq() {
        return latEsqIzq;
    }

    public static double getEscala() {
        return escala;
    }

    public static String getDatum() {
        return datum;
    }

    public static int getNumFilas() {
        return numFilas;
    }

    public static int getNumColumnas() {
        return numColumnas;
    }

    public static String getRutaImagen() {
        return rutaImagen;
    }

    public static String getFicheroImagen() {
        return ficheroImagen;
    }

    public static String getExtensionImagen() {
        return extensionImagen;
    }

    /**
     * @param aNumFilas the numFilas to set
     */
    public static void setNumFilas(int aNumFilas) {
        numFilas = aNumFilas;
    }

    /**
     * @param aNumColumnas the numColumnas to set
     */
    public static void setNumColumnas(int aNumColumnas) {
        numColumnas = aNumColumnas;
    }
}
